#!/public/home/jwli/workSpace/yongkang/.nvm/versions/node/v16.20.2/bin/node
const _ = require('lodash');
const csv = require('csv/sync');
const fs = require('fs');
const argv = require("minimist")(process.argv.slice(2));

function readFileAsync(filePath) {
    return new Promise((resolve, reject) => {
        fs.readFile(filePath, 'utf8', (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

if (argv.copyFlag) {
    const old_log_func = console.log;
    console.log = function(...argArr) {
        old_log_func(argArr[argArr.length-1]);
    }
}


// Usage example:
// readFileAsync('/home/lic/syntcomp2024/synviasat-21FP-js-migrate/output_syntcomp23_nike.csv')
readFileAsync(argv.path)
    .then(csv_txt => {
        const parseData = csv.parse(csv_txt, {
            columns: true,
            delimiter: ', ',
        });
        const resKeyStr = Object.keys(parseData[0]).includes('ResultType') ? 'ResultType' : 'Result';
        const resultTypes = ['Realizable', 'Unrealizable'];
        if (argv.casesFlag) {
            const totalSolvedData = parseData.filter(data => {
                return resultTypes.some((resType) => data[resKeyStr].toLowerCase().endsWith(resType.toLowerCase()))
            });
            console.log('Total Solved:\t', totalSolvedData.length);
            console.log('');    // to create a blank line!!!

            const resultCases = ['Precheck-unrealizable', 'Precheck-realizable', 'Dfa-realizable', 'Dfa-unrealizable', 'NoResFile', 'Stopped'];
            const allResults = parseData.map((item) => item[resKeyStr]);
            const allPossibleResultType = [...new Set(resultCases.concat(allResults))]
            allPossibleResultType.sort();
            allPossibleResultType.map((resType) => {
                const num = parseData.filter((item) => item[resKeyStr] == resType).length;
                // return {num, resType};
                console.log(resType + ': ' + num);
            })
            allPossibleResultType.splice(allPossibleResultType.indexOf('Stopped'), 1);
            allPossibleResultType.splice(allPossibleResultType.indexOf('NoResFile'), 1);
            // console.log(allPossibleResultType.join('\n'));
            allPossibleResultType.map((resType) => {
                const num = parseData.filter((item) => item[resKeyStr] == resType).length;
                // return {num, resType};
                console.log(num);
            })
            return ;
        }
        const totalSolvedData = parseData.filter(data => resultTypes.includes(data[resKeyStr]))
        console.log('Total Solved:\t', totalSolvedData.length);
        console.log('');    // to create a blank line!!!
        // console.log(parseData);
        /**
         * Patterns
         * Random           Realizable
         * Random           Unrealizable
         * Ascending        Realizable
         *                  Unrealizable
         * Two-player-games s-counter
         *                  d-counter
         *                  nim
         * Uniquely solved  Realizable
         *                  Unrealizable
         */
        /* Patterns: Folder property is GFand or Uright */
        const patternsData = parseData.filter(data => data['Folder'] === 'GFand' || data['Folder'] === 'Uright');
        const patternsSolvedData = patternsData.filter(data => resultTypes.includes(data[resKeyStr]))
        console.log('Patterns Solved:\t', patternsSolvedData.length);
        /* Random: Folder property startsWith case or syft */
        const randomData = parseData.filter(data => data['Folder'].startsWith('case') || data['Folder'].startsWith('syft'));
        const randomGroupData = _.groupBy(randomData, resKeyStr);
        resultTypes.forEach((resultType) => {
            console.log(`Random ${resultType}:\t`, randomGroupData[resultType]?.length || 0);
        });
        /* Ascending: Folder property is matched with t\d+ */
        const ascendingData = parseData.filter(data => data['Folder'].match(/^t\d+$/));
        const ascendingGroupData = _.groupBy(ascendingData, resKeyStr);
        resultTypes.forEach((resultType) => {
            console.log(`Ascending ${resultType}:\t`, ascendingGroupData[resultType]?.length || 0);
        });
        // 'Single-Counter', 'Double-Counter', 'nim_\\d+'
        const two_player_games_Folders = [
            { name: 'Single-Counter', regexStr: 'Single-Counter' },
            { name: 'Double-Counter', regexStr: 'Double-Counter' },
            { name: 'Nim', regexStr: 'nim_\\d+' },
        ];
        /* Two-player-games */
        two_player_games_Folders.forEach((folderItem) => {
            const twoPlayerGamesData = parseData.filter(data => data['Folder'].match(new RegExp(folderItem.regexStr)));
            const twoPlayerGamesSolvedData = twoPlayerGamesData.filter(data => resultTypes.includes(data[resKeyStr]));
            const padSpaceStr = folderItem.name.length < 8 ? '\t' : '';
            console.log(`${folderItem.name} Solved:${padSpaceStr}\t`, twoPlayerGamesSolvedData.length);
        })
    })
    .catch(err => {
        console.error('Error reading file:', err);
    });
